package cn.arnold.queue;

/**
 * 环形数组实现队列
 */
public class CircleArrayQueue {
    // s数组最大容量
    private int size;
    // 数组头指针
    private int front;
    // 数组尾指针
    private int rear;
    // 数组
    private int[] arrayQueue;

    //构造器
    public CircleArrayQueue(int maxSize) {
        this.size = maxSize;
        arrayQueue = new int[size];
        // 初始值赋值为0
        this.front = 0;
        this.rear = 0;
    }

    // 数组是否为空:front==rear
    public boolean isEmpty() {
        return front == rear;
    }

    // 数组是否已满:(rear+1)%size==front
    public boolean isFull() {
        return (rear + 1) % size == front;
    }

    // 队列中的有效个数:(rear+size-front)%size
    public int availableValue() {
        return (rear + size - front) % size;
    }

    // 添加数据:从rear添加；rear后移一位:考虑取模---(rear + 1) % size
    public void addQueue(int value) {
        if (isFull()) {
            throw new RuntimeException("数组已满，无法添加");
        }
        arrayQueue[rear] = value;
        // rear后移一位:考虑取模
        rear = (rear + 1) % size;
    }

    // 取数据：从front添加；front后移一位:考虑取模---(front + 1) % size
    public int getQueue() {
        if (isEmpty()) {
            throw new RuntimeException("空数组，无法操作");
        }
        int temp = arrayQueue[front];
        // front后移
        front = (front + 1) % size;
        return temp;
    }

    // 显示队列数据
    public void showQueue() {
        if (isEmpty()) {
            throw new RuntimeException("空数组");
        }
        // 从front开始遍历
        int availableValue = availableValue();
        for (int i = front; i < front + availableValue; i++) {
            System.out.println(arrayQueue[i % size]);
        }
    }

    // 显示第一个数据
    public int showHead() {
        if (isEmpty()) {
            throw new RuntimeException("空数组");
        }
        return arrayQueue[front];
    }
}
